using System;
using System.Reflection;
using System.Collections.Generic;

namespace Open.Data.Persistence
{
    //Strongly typed key value pair collection for ReflectionCache items
    public sealed class ReflectionCache: Dictionary<Type, CacheItem>
    {
        private IProvider _provider;
        private ReflectionParser _parser;

        //Constructors
        public ReflectionCache(IProvider provider)
        {
            _provider = provider;
        }

        //Methods
        public CacheItem Lookup(Type type)
        {
            if (type == null) throw new ReflectionCacheException("Type may not be null when retrieving a cache item.");

            CacheItem item = null;
            
            //Try get the item from cache. Item is output variable
            if (! this.TryGetValue(type, out item))
            {
                //Rerieve a parser from the provider
                if (_parser == null) _parser = _provider.CreateParser();
                
                //Reset, validate and parse the type
                _parser.Reset();
                _parser.Parse(type);
                _parser.Validate(type);

                //Create a new cache item with the parser values
                item = _provider.CreateCacheEntry(type, _parser);

                //Add to the reflection cache
                Add(type, item);
            }

            return item;
        }
    }
}
